package com.lzx.adx.report.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lzs.adx.commmon.service.impl.CrudServiceImpl;
import com.lzx.adx.report.cache.AccountLocalCache;
import com.lzx.adx.report.dao.BackDataDao;
import com.lzx.adx.report.dto.AccountDTO;
import com.lzx.adx.report.dto.BackDataDTO;
import com.lzx.adx.report.dto.ReportDTO;
import com.lzx.adx.report.entity.BackDataEntity;
import com.lzx.adx.report.model.address.AddressInfoDTO;
import com.lzx.adx.report.service.BackDataService;
import com.lzx.adx.report.util.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * 
 *
 * @author wangzhijun 825400558@qq.com
 * @since 1.0.0 2024-07-05
 */
@Service
@Slf4j
public class BackDataServiceImpl extends CrudServiceImpl<BackDataDao, BackDataEntity, BackDataDTO> implements BackDataService {


    @Override
    public QueryWrapper<BackDataEntity> getWrapper(Map<String, Object> params){
        String id = (String)params.get("id");
        String bizRequestId = (String)params.get("bizRequestId");

        QueryWrapper<BackDataEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(id), "id", id);
        wrapper.eq(StringUtils.isNotBlank(bizRequestId), "biz_request_id", bizRequestId);
        wrapper.orderByDesc("day");

        return wrapper;
    }


    @Override
    public void saveData(ReportDTO report, String eventType) {
        AccountDTO accountDTO = AccountLocalCache.getInstance().get(report.getDspId());
        synchronized (this) {
            String format = DateUtil.format(new Date(), createFormatter("yyyy-MM-dd"));
            BackDataEntity backData = new BackDataEntity();
            backData.setDay(format);
            backData.setCreateTime(new Date());
            backData.setEventType(eventType);
            backData.setBizRequestId(report.getBizRequestId());
            backData.setDspId(report.getDspId());
            backData.setParamsExtends(report.getExtend());
            backData.setIp(report.getIp());
            //获取地址
            AddressInfoDTO address = IpUtils.getAddress(report.getIp());
            backData.setProvince(address.getProvince());
            backData.setCity(address.getCity());
            //设置监测的Md5
            if(StringUtils.isNotBlank(accountDTO.getDspReportUrl())) {
                backData.setUrlMd5(SecureUtil.md5(accountDTO.getDspReportUrl()));
            }
            //幂等处理
            LambdaQueryWrapper<BackDataEntity> queryWrapper = new LambdaQueryWrapper();
            queryWrapper.eq(BackDataEntity::getDspId, report.getDspId());
            queryWrapper.eq(BackDataEntity::getDay, format);
            queryWrapper.eq(BackDataEntity::getEventType, eventType);
            queryWrapper.eq(BackDataEntity::getBizRequestId, report.getBizRequestId());
            List<BackDataEntity> backDataEntities = baseDao.selectList(queryWrapper);
            if (CollectionUtil.isNotEmpty(backDataEntities)) {
                log.info("账户ID{},日期为{},流水号为{},事件类型为{},已存在当前事件，不计入统计", report.getDspId(), format, report.getBizRequestId(), eventType);
            } else {
                this.baseDao.insert(backData);
            }
        }
    }

    @Override
    public long countTotal(String id, String callType) {

        return  this.baseDao.countTotal(id,callType);
    }

    @Override
    public long countCurrentDayTotal(String id, String callType, String day) {

        return  this.baseDao.countCurrentDayTotal(id,callType,day);
    }

    public static DateTimeFormatter createFormatter(String pattern) {
        return DateTimeFormatter.ofPattern(pattern, Locale.getDefault())
                .withZone(ZoneId.systemDefault());
    }
}